﻿using System.Collections.Generic;

namespace Sidvall.Data
{
    public class ObjectParameterCollection : System.Collections.ObjectModel.KeyedCollection<string, ObjectParameter>
    {
        #region Public Members

        #region Add

        public void Add(string key, object value)
        {
            var item = new ObjectParameter()
            {
                Key = key,
                Value = value,
            };
            Add(item);
        }

        #endregion
        #region AddOrUpdate

        public void AddOrUpdate(string key, object value)
        {
            if (key == null)
                return;
            lock (_Mutex)
            {
                var existingItem = FindObjectParameter(key);
                if (existingItem != null)
                    existingItem.Value = value;
                else
                    Add(key, value);
            }
        }

        #endregion
        #region FindObjectParameter

        public ObjectParameter FindObjectParameter(string key)
        {
            if (key == null)
                return null;
            if (Contains(key))
                return this[key];
            return null;
        }

        #endregion
        #region GetKeyForItem

        protected override string GetKeyForItem(ObjectParameter item)
        {
            if (item == null)
                throw new System.ArgumentNullException(nameof(item));

            return item.Key;
        }

        #endregion
        #region GetValue

        public T GetValue<T>(string key)
        {
            return GetValue(key, default(T));
        }
        public T GetValue<T>(string key, T defaultValue)
        {
            var item = FindObjectParameter(key);
            if (item == null)
                return defaultValue;
            return (T)item.Value;
        }

        #endregion
        #region Merge

        public void Merge(ObjectParameter item)
        {
            if (item == null)
                return;
            AddOrUpdate(item.Key, item.Value);
        }
        public void Merge(IEnumerable<ObjectParameter> items)
        {
            if (items == null)
                return;
            foreach (var item in items)
                Merge(item);
        }

        #endregion

        #endregion
        #region Private Members

        private readonly object _Mutex = new object();

        #endregion
        #region Constructors

        public ObjectParameterCollection()
        {
        }

        #endregion
    }
}
